package com.meisupic.copyright.service.impl;

import com.meisupic.copyright.common.PayWayEnum;
import com.meisupic.copyright.domain.po.AccountInfo;
import com.meisupic.copyright.domain.po.BusinessCooperationInfo;
import com.meisupic.copyright.domain.po.MemberCategoryPo;
import com.meisupic.copyright.domain.po.RealNameAuth;
import com.meisupic.copyright.domain.po.SerialNumber;
import com.meisupic.copyright.domain.po.Users;
import com.meisupic.copyright.domain.po.VipMemberPo;
import com.meisupic.copyright.domain.po.VipOrder;
import com.meisupic.copyright.domain.vo.AccountInfoVo;
import com.meisupic.copyright.domain.vo.RealNameAuthVo;
import com.meisupic.copyright.domain.vo.ScanPayResultVO;
import com.meisupic.copyright.domain.vo.VipUserVo;
import com.meisupic.copyright.exception.BizException;
import com.meisupic.copyright.repo.AccountInfoRepo;
import com.meisupic.copyright.repo.BusinessCooperationInfoRepo;
import com.meisupic.copyright.repo.MemberCategoryRepo;
import com.meisupic.copyright.repo.SerialNumberRepo;
import com.meisupic.copyright.repo.UsersRepo;
import com.meisupic.copyright.repo.VipMemberRepo;
import com.meisupic.copyright.repo.VipOrderRepo;
import com.meisupic.copyright.service.IAccountService;
import com.meisupic.copyright.service.IRealNameAuthService;
import com.meisupic.copyright.service.IWeiXinPayService;
import com.meisupic.copyright.service.VipMemberService;
import com.meisupic.copyright.support.PageResponse;
import com.meisupic.copyright.support.security.CustomPasswordEncode;
import com.meisupic.copyright.util.BeanMapper;
import com.meisupic.copyright.util.BeanUtil;
import com.meisupic.copyright.util.DateUtil;
import com.meisupic.copyright.util.StringUtil;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

/**
 * @Author lanjian
 * @Date 2018/3/11 下午3:33
 */
@Service
public class AccountServiceImpl implements IAccountService {

  @Value("${vip.price:1999}")
  private Double vipPrice;

  @Autowired
  private AccountInfoRepo accountInfoRepo;

  @Autowired
  private IRealNameAuthService realNameAuthService;

  @Autowired
  private IWeiXinPayService weiXinPayService;

  @Autowired
  private VipMemberService vipMemberService;

  @Autowired
  private VipOrderRepo vipOrderRepo;

  @Autowired
  private SerialNumberRepo serialNumberRepo;

  @Autowired
  private UsersRepo usersRepo;

  @Autowired
  private BusinessCooperationInfoRepo businessCooperationInfoRepo;

  @Autowired
  private MemberCategoryRepo memberCategoryRepo;

  @Autowired
  private VipMemberRepo vipMemberRepo;

  @Value("${wx.pay.notify.url}")
  private String notifyUrl;

  @Override
  public AccountInfoVo getAccountInfo(Long userId) {
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
    if (StringUtil.isEmpty(realNameAuth)) {
      // 100101 用于前台判断是否实名认证
      throw new BizException("100101");
    }
    AccountInfo accountInfo = getByUserId(userId);
    if (StringUtil.isEmpty(accountInfo)) {
      AccountInfoVo accountInfoVo = new AccountInfoVo();
      accountInfoVo.setMobile(realNameAuth.getMobile());
      accountInfoVo.setBankAccountName(realNameAuth.getAuthName());
      return accountInfoVo;
    }
    AccountInfoVo accountInfoVo = BeanMapper.map(accountInfo, AccountInfoVo.class);
    accountInfoVo.setMobile(realNameAuth.getMobile());
    return accountInfoVo;
  }

  @Override
  public void updateAccountInfo(AccountInfoVo accountInfoVo, Long userId) {
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
    if (StringUtil.isEmpty(realNameAuth)) {
      // 100101 用于前台判断是否
      throw new BizException("请实名认证后设置账户信息");
    }
    AccountInfo accountInfo = getByUserId(userId);
    if (StringUtil.isEmpty(accountInfo)) {
      accountInfo = BeanMapper.map(accountInfoVo, AccountInfo.class);
      accountInfo.setBankAccountName(realNameAuth.getAuthName());
    } else {
      BeanUtil.copyPropertiesIgnoreNull(accountInfoVo, accountInfo);
    }
    accountInfo.setUserId(userId);
    accountInfoRepo.save(accountInfo);
  }

  @Override
  public AccountInfo getByUserId(Long userId) {
    List<AccountInfo> accountInfos = accountInfoRepo.findByUserId(userId);
    if (StringUtil.isEmpty(accountInfos)) {
      return null;
    }
    return accountInfos.get(0);
  }

  @Override
  public RealNameAuthVo getRealNameAuthInfo(Long userId) {
    RealNameAuth realNameAuth = realNameAuthService.findByUserId(userId);
    if (realNameAuth == null) {
      return null;
    }
    RealNameAuthVo realNameAuthVo = BeanMapper.map(realNameAuth, RealNameAuthVo.class);
    return realNameAuthVo;
  }

  @Override
  public VipOrder addVipOrder(VipOrder vipOrder) {
    Date invalidDate = DateUtil.getOffsiteDate(new Date(), Calendar.YEAR, 1);
    String orderNo_suffix = DateUtil.format(new Date(), "yyyyMMdd");
    vipOrder.setOrderNo(getOrderNo(orderNo_suffix));
    vipOrder.setInvalidTime(invalidDate);
    vipOrder = vipOrderRepo.save(vipOrder);
    return vipOrder;
  }

  /**
   * 获取用户24小时内待支付的订单
   */
  @Override
  public VipOrder queryToPayVipOrder(Long userId) {
    Date orderTimeBefore = DateUtil.getOffsiteDate(new Date(), Calendar.HOUR, -24);
    VipOrder vipOrder = vipOrderRepo.findVipOrderByUserIdAndOrderTimeAfter(userId, orderTimeBefore);
    return vipOrder;
  }

  @Override
  public VipOrder findVipOrderByOrderNo(String orderNo) {
    return vipOrderRepo.findVipOrderByOrderNo(orderNo);
  }

  @Override
  public VipOrder findVipOrderById(Long id) {
    return vipOrderRepo.findOne(id);
  }

  @Override
  public Boolean isVip(Long userId) {
//    VipOrder vipOrder = vipOrderRepo
//        .findVipOrderByInvalidTimeAfterAndUserIdAndPayStatusIs(new Date(), userId, true);

    return vipMemberService.isVip(userId);
  }

  @Override
  public ScanPayResultVO getWeixinPayQrcode(String orderNo) {

    if (StringUtil.isEmpty(orderNo)) {
      throw new BizException("订单id不能为空");
    }
    VipOrder vipOrder = vipOrderRepo.findVipOrderByOrderNo(orderNo);
    if (StringUtil.isEmpty(vipOrder)) {
      throw new BizException("未找到订单");
    } else {
      if (vipOrder.getPayStatus()) {
        throw new BizException("订单已支付");
      }
    }
    ScanPayResultVO scanPayResultVO = weiXinPayService
        .initScanPay(String.valueOf(orderNo), "VIP会员费", "", vipOrder.getOrderPrice(), notifyUrl,
            "127.0.0.1");
    scanPayResultVO.setOrderNo(vipOrder.getOrderNo());
    return scanPayResultVO;
  }

  /**
   * 支付完成
   */
  public void completePayOrder(String orderNo, PayWayEnum payWay, Date payTime) {
    VipOrder vipOrder = vipOrderRepo.findVipOrderByOrderNo(orderNo);
    vipOrder.setPayWay(payWay);
    vipOrder.setPayTime(payTime);
    vipOrder.setPayStatus(true);
    vipOrderRepo.save(vipOrder);

    MemberCategoryPo categoryPo = memberCategoryRepo.findOne(vipOrder.getMemberCategoryId());
    Date invalidDate = DateUtil.getOffsiteDate(new Date(), Calendar.YEAR, 1);

    VipMemberPo vipMemberPo = new VipMemberPo();
    vipMemberPo.setMemberCategoryId(vipOrder.getMemberCategoryId());
    vipMemberPo.setMemberCategoryName(categoryPo.getCategoryName());
    vipMemberPo.setOrderNo(orderNo);
    vipMemberPo.setLeftAmount(categoryPo.getServiceTotal());
    vipMemberPo.setTotal(categoryPo.getServiceTotal());
    vipMemberPo.setPrice(categoryPo.getDiscountPrice());
    vipMemberPo.setUserId(vipOrder.getUserId());
    vipMemberPo.setExpiryDate(invalidDate);
    vipMemberPo.setCreateDate(new Date());
    vipMemberRepo.save(vipMemberPo);
  }

  @Override
  public void updatePassword(Long userId, String password, String newPassword) {
    Users users = usersRepo.findOne(userId);
    String password_curr = users.getPassword();
    String salt = users.getSalt();
    CustomPasswordEncode customPasswordEncode = new CustomPasswordEncode();
    boolean isValid = customPasswordEncode.isPasswordValid(password_curr, password, salt);
    if (!isValid) {
      throw new BizException("密码错误");
    }

    String enpass = customPasswordEncode.encodePassword(newPassword, salt);
    usersRepo.updatePassword(enpass, userId);
  }

  @Override
  public void saveBusinessCooperation(BusinessCooperationInfo businessCooperationInfo) {
    businessCooperationInfoRepo.save(businessCooperationInfo);
  }

  @Override
  public boolean isHuabanUser(Long userId) {
    Users users = usersRepo.findOne(userId);
    return !StringUtil.isEmpty(users.getHuabanUserId());
  }

  private String getOrderNo(String suffix) {
    SerialNumber serialNumber = new SerialNumber();
    serialNumber.setBusinessCode(suffix);
    serialNumber = serialNumberRepo.findOne(Example.of(serialNumber));
    Integer currentValue = 1;
    if (serialNumber == null) {
      serialNumber = new SerialNumber();
      serialNumber.setBusinessCode(suffix);
      serialNumber.setCurrentValue(currentValue);
    } else {
      currentValue = serialNumber.getCurrentValue() + 1;
      serialNumber.setCurrentValue(currentValue);
    }
    serialNumberRepo.save(serialNumber);
    return suffix + String.format("%04d", currentValue);
  }


  public PageResponse<VipUserVo> getVipUsers(Pageable pageable) {
    Page<VipUserVo> page = vipMemberRepo.findVipUser(pageable);
    List<VipUserVo> vipUserVos = page.getContent();
    PageResponse<VipUserVo> vipUserVoPage = new PageResponse<>(
        page.getTotalElements(), vipUserVos);
    return vipUserVoPage;
  }
}
